GNU Debugger (GDB)
Starting GDB
GDB is a powerful tool for debugging programs. It allows you to inspect the state of a program at a certain point in its execution, set breakpoints, and step through the code, among other things. To start GDB, you need to run the following command:
gdb [program_name]
Running the Program
To run the program being debugged, there are two available commands:
r
orrun
- this command will run the programstart
- unlikerun
, this command will start the program but immediately stop after enteringmain
, it is equivalent to setting a breakpoint atmain
and then running the program
Breakpoints
The essential element of GDB is the breakpoint. Essentially, setting a breakpoint at a certain instruction causes the program's execution to halt every time it reaches that point. Setting a breakpoint is done with the following command:
break [location]
or in short form:
b [location]
where location can represent the name of a function, the line number of the code, or even a memory address, in which case the address must be preceded by the symbol *.
For example: break \*0xCAFEBABE
Stepping through instructions
si
orstepi
- executes the current instructionni
ornexti
- similar tostepi
, but if the current instruction is a function call, the debugger will not enter the functionc
orcontinue
- continues program execution until the next breakpoint or until it finishesfinish
- continues program execution until leaving the current function
Inspecting Memory
p
orprint
var - displays the value ofvar
. Print is a very flexible command, allowing dereferencing of pointers, displaying addresses of variables, and indexing through arrays using *, & and []. The print command can be followed by the /f parameter specifying the display format (x for hex, d for decimal, s for string).x
orexamine
- Inspects the content at the given address. The usage of this command is as follows:
x/nfu address
where:
- n is the number of displayed elements
- f is the display format (x for hex, d for decimal, s for string, and i for instructions)
- u is the size of each element (b for 1 byte, h for 2, w for 4, and g for 8 bytes)
We recommend the article Debugging for further understanding of how to use GDB both in the CLI and through an IDE.
pwndbg
pwndbg is a GDB plugin that provides a number of useful features for debugging and exploiting binaries. It makes GDB easier to use and infinitely more powerful. It will become more useful as we progress through the lab sessions.
Cheatsheet gdb + pwndbg; pwndbg features
pwndbg> show context-sections
'regs disasm code ghidra stack backtrace expressions'
# for smaller terminals
pwndbg> set context-sections 'regs code stack'
# display memory area in hex + ASCII
pwndbg> hexdump $ecx
# display stack
pwndbg> stack
# permanently display memory dump of 8 bytes
pwndbg> ctx-watch execute "x/8xb &msg"
# recommended settings in .gdbinit
set context-sections 'regs code expressions'
set show-flags on
set dereference-limit 1